import Dot from "./Dot";

export interface IFontEffects {
    canvas:HTMLCanvasElement
    dotAmount:number
}

export interface IPosition {
    x:number
    y:number
}


export default class FontEffects{

    private readonly _context:CanvasRenderingContext2D|null;
    private readonly _canvas:HTMLCanvasElement;
    private _position:IPosition[] = [];
    private _dotArray:Dot[] = [];
    private _fps:number = 0;
    private _text:string = 'cofeCat';
    private _text2:string = 'coffeeCat';
    private _textArray:string[];
    private _count=0;
    private readonly _dotAmount:number;

    constructor(props:IFontEffects){
        const {canvas, dotAmount} = props;
        this._dotAmount = dotAmount;
        this._canvas = canvas;
        this._context = this._canvas.getContext('2d');
        const width = getComputedStyle(this._canvas).width;
        const height = getComputedStyle(this._canvas).height;
        this.setCanvas(width, height);
        this.sliceText(this._text);
        this.createDot();
    }

    /**
     * 创建dot,并给予颜色和随机位置
     */
    createDot():number{
        if(this._context===null)return -1;
        const context = this._context;
        const width = this._canvas.width;
        const height = this._canvas.height;
        const size = 2;
        for(let i=0;i<this._dotAmount;i++){
            const position_x = Math.floor(Math.random()*width);
            const position_y = Math.floor(Math.random()*height);
            this._dotArray.push(new Dot({
                x:position_x,
                y:position_y,
                context,
                size}));
        }
        return 1;
    }

    /**
     * 将字符串分割成字符串数组
     * @param text
     */
    sliceText(text:string):string[]{
        this._textArray = text.split('');
        this._textArray.push(this._text2);
        return this._textArray;
    }

    /**
     * 获取文字所有像素的x,y坐标
     * @param context
     * @param canvas
     */
    getImageData(context:CanvasRenderingContext2D|null, canvas:HTMLCanvasElement|null):number{
        if(context===null||canvas===null)return -1;
        const t = context.getImageData(0, 0, canvas.width, canvas.height);
        const length = t.data.length;

        this._position = [];
        for(let i=0;i<length;i++){
            if(t.data[i]!==0){
                let p = i/4;
                this._position.push({
                    x:p%canvas.width,
                    y:p/canvas.width
                });
            }
        }

        context.clearRect(0,0, canvas.width, canvas.height);
        return 1;
    }

    /**
     * 绘制文字
     * @param context
     */
    drawText(context:CanvasRenderingContext2D|null):number{
        if(context===null){
            return -1;
        }
        context.fillStyle = '#000';
        const length =  this._textArray.length;
        this._count===length-1?
            context.font = '100px sans-serif':
            context.font = '130px sans-serif';
        const text = this._textArray[this._count%length];
        this._count++;
        if(this._count>length-1)this._count=0;
        context.textAlign = "center";
        context.textBaseline = "middle";
        context.fillText(text, (this._canvas.width / 2), (this._canvas.height / 2));
        return 1;
    }


    /**
     * 绘制由其他元素构成的文字
     */
    draw():number{
        const context = this._context;
        if(context===null){
            return -1;
        }
        const canvas = this._canvas;
        context.clearRect(0,0, canvas.width, canvas.height);
        if(this._fps%60===0){
            this.drawText(this._context);
            this.getImageData(this._context, this._canvas);
        }
        this._fps++;
        const position = this._position;
        const length = this._dotArray.length;
        const interval = this._position.length/length;
        if(length>this._position.length){
            this.drawDot2(this._position.length, position);
        }else{
            this.drawDot1(interval, position);
        }
        return 1;
    }

    /**
     * dot少于或等于所需要时执行
     * @param interval
     * @param position
     */
    drawDot1(interval:number, position:IPosition[]){
        const length = this._dotArray.length;
        for(let i=0;i<length;i++) {
            const t = Math.floor(interval*i);
            this._dotArray[i].move(position[t].x, position[t].y);
        }

    }

    /**
     * dot多余所需时执行
     * @param interval
     * @param position
     */
    drawDot2(interval:number, position:IPosition[]){
        const length = this._dotArray.length;
        for(let i=0;i<length;i++){
            const t= i%(position.length-1);
            this._dotArray[i].move(position[t].x, position[t].y);
        }
    }

    /**
     * 设置canvas
     * @param width canvas的宽
     * @param height  canvas的高
     * */
    setCanvas(width:string|number|null, height:string|number|null):number{
        if(width === null || height === null){
            console.error('width or height is error');
            return -1;
        }
        if(typeof width ==='number'){
            this._canvas.width = width;
        }else {
            this._canvas.width = Number(width.replace('px',''));
        }
        if(typeof height === 'number'){
            this._canvas.height = height;
        }else {
            this._canvas.height = Number(height.replace('px',''));
        }
        return 1;
    }

}


